package com.smile.service.handler;

import com.alibaba.fastjson2.JSONObject;
import com.smile.mapper.WayPointTaskInfoMapper;
import com.smile.service.config.mqtt.handler.AbstractStorageConfigGetHandler;
import com.smile.service.entity.media.StorageConfigGetData;
import com.smile.service.entity.response.DeviceConfigResponse;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.credentials.AssumeRoleProvider;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;

@Component
@Slf4j
public class DefaultStorageConfigGetHandler extends AbstractStorageConfigGetHandler {


    @Value("${oss.endpoint}")
    public String endpoint;

    @Value("${oss.bucketName}")
    public String bucketName;

    @Value("${oss.region}")
    public String region;

    @Value("${oss.accessKeyId}")
    public String accessKeyId;

    @Value("${oss.accessKeySecret}")
    public String accessKeySecret;

    @Value("${oss.sts.endpoint}")
    public String stsEndpoint;

    @Value("${oss.sts.roleArn}")
    public String roleArn;

    @Value("${oss.sts.roleSessionName}")
    public String roleSessionName;

    @Value("${oss.sts.durationSeconds}")
    public Long durationSeconds;


    @Autowired
    private WayPointTaskInfoMapper wayPointTaskInfoMapper;


//    //服务所在ip地址和端口
//    public static final String ENDPOINT = "http://192.168.0.80:9000/";
//
//    //mc的用户名
//    public static final String ACCESS_KEY_COMPANY = "feisuan123456";
//    //mc的密码
//    public static final String SECRET_KEY_COMPANY = "feisuan123456";
//    //aws服务端点
//    public static final String REGION = "hz";
//    //上传的bucket名
//    public static final String BUCKET = "my-bucket";
//    //授权策略，允许访问名为bucket的桶的目录
//    public static final String ROLE_ARN = "arn:aws:s3:::my-bucket/*";
//    public static final String ROLE_SESSION_NAME = "anysession";
//    //定义策略，可进行二次限定
//    public static final String POLICY_GET_AND_PUT = "{\n" +
//            "    \"Version\": \"2012-10-17\",\n" +
//            "    \"Statement\": [\n" +
//            "        {\n" +
//            "            \"Effect\": \"Allow\",\n" +
//            "            \"Action\": [\n" +
//            "                \"s3:GetBucketLocation\",\n" +
//            "                \"s3:PutObject\",\n" +
//            "                \"s3:ListBucket\"\n" +
//            "            ],\n" +
//            "            \"Resource\": [\n" +
//            "                \"arn:aws:s3:::my-bucket\"\n" +
//            "            ]\n" +
//            "        },\n" +
//            "        {\n" +
//            "            \"Effect\": \"Allow\",\n" +
//            "            \"Action\": [\n" +
//            "                \"s3:GetObject\"\n" +
//            "            ],\n" +
//            "            \"Resource\": [\n" +
//            "                \"arn:aws:s3:::my-bucket/*\"\n" +
//            "            ]\n" +
//            "        }\n" +
//            "    ]\n" +
//            "}";


    /**
     * 得到 临时凭据
     */
    public static void main(String[] args) {
        System.out.println(POLICY_GET_AND_PUT);

        try {
            System.out.println("开始测试MinIO STS服务...");

            // 调试信息
            System.out.println("ENDPOINT: " + ENDPOINT);
            System.out.println("ACCESS_KEY: " + ACCESS_KEY_COMPANY);
            System.out.println("BUCKET: " + BUCKET);

            // 测试基本连接
            testMinIOConnection();

            // 获取STS凭据
            io.minio.credentials.Credentials credentials = getCredentials();

            System.out.println("STS凭据获取成功:");
            System.out.println("AccessKey: " + credentials.accessKey());
            System.out.println("SecretKey: " + credentials.secretKey());
            System.out.println("SessionToken: " + credentials.sessionToken());
            System.out.println("Expired: " + credentials.isExpired());

        } catch (Exception e) {
            System.err.println("错误信息: " + e.getMessage());
            e.printStackTrace();

            // 如果是MinIO特定的异常
            if (e instanceof io.minio.errors.ErrorResponseException) {
                io.minio.errors.ErrorResponseException ere = (io.minio.errors.ErrorResponseException) e;
                System.err.println("错误代码: " + ere.errorResponse().code());
                System.err.println("错误消息: " + ere.errorResponse().message());
            }
        }
    }

    // 修正的常量定义
// 服务所在ip地址和端口（去掉末尾斜杠）
    public static final String ENDPOINT = "http://192.168.0.80:9000";

    // MinIO的用户名和密码
    public static final String ACCESS_KEY_COMPANY = "feisuan123456";
    public static final String SECRET_KEY_COMPANY = "feisuan123456";

    // 区域（MinIO通常使用"us-east-1"）
    public static final String REGION = "hz";

    // 上传的bucket名
    public static final String BUCKET = "my-bucket";

    // 对于MinIO，roleArn通常为null或空字符串
    public static final String ROLE_ARN = "";

    public static final String ROLE_SESSION_NAME = "minio-session";

    // 修正的策略定义（使用单行格式避免转义问题）
    public static final String POLICY_GET_AND_PUT =
            "{\n" +
                    " \"Version\": \"2012-10-17\",\n" +
                    " \"Statement\": [\n" +
                    "  {\n" +
                    "   \"Effect\": \"Allow\",\n" +
                    "   \"Action\": [\n" +
                    "    \"s3:GetObject\",\n" +
                    "    \"s3:ListBucket\",\n" +
                    "    \"s3:PutObject\",\n" +
                    "    \"s3:DeleteObject\",\n" +
                    "    \"s3:GetBucketLocation\"\n" +
                    "   ],\n" +
                    "   \"Resource\": [\n" +
                    "    \"arn:aws:s3:::my-bucket\",\n" +
                    "    \"arn:aws:s3:::my-bucket/*\"\n" +
                    "   ]\n" +
                    "  }\n" +
                    " ]\n" +
                    "}";


    /**
     * 测试MinIO基本连接
     */
    private static void testMinIOConnection() throws Exception {
        MinioClient minioClient = MinioClient.builder()
                .endpoint(ENDPOINT)
                .credentials(ACCESS_KEY_COMPANY, SECRET_KEY_COMPANY)
                .build();

        // 测试服务器是否可达
        System.out.println("测试MinIO服务器连接...");
        minioClient.listBuckets();
        System.out.println("MinIO服务器连接成功");

        // 检查bucket是否存在
        boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder()
                .bucket(BUCKET)
                .build());

        if (bucketExists) {
            System.out.println("Bucket '" + BUCKET + "' 存在");
        } else {
            System.out.println("Bucket '" + BUCKET + "' 不存在，请先创建bucket");
            // 可以选择自动创建bucket
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET).build());
            System.out.println("已创建bucket: " + BUCKET);
        }
    }

    /**
     * 获取临时凭据
     */
    private static io.minio.credentials.Credentials getCredentials() throws Exception {
        int durationSeconds = 3600; // 使用标准值

        System.out.println("创建AssumeRoleProvider...");

        AssumeRoleProvider provider = new AssumeRoleProvider(
                ENDPOINT,
                ACCESS_KEY_COMPANY,
                SECRET_KEY_COMPANY,
                durationSeconds,
                POLICY_GET_AND_PUT,
                REGION,
                ROLE_ARN,          // 对于MinIO通常为null
                ROLE_SESSION_NAME,
                null,
                null);

        System.out.println("获取STS凭据...");
        return provider.fetch();
    }


    @Override
    public Boolean process(String data, String tid, String bid, String gateway) throws MqttException, NoSuchAlgorithmException {


        String adminAccessKey = "minioadmin";  // 默认管理员
        String adminSecretKey = "minioadmin";  // 默认密码

        AssumeRoleProvider provider = new AssumeRoleProvider(
                "http://192.168.0.80:9000",
                adminAccessKey,
                adminSecretKey,
                3600,
                null,
                "hz",
                null,
                "admin-session",
                null,
                null);

        io.minio.credentials.Credentials credentials = provider.fetch();

        StorageConfigGetData.StorageCredentials storageCredentials = new StorageConfigGetData.StorageCredentials();
        storageCredentials.setAccessKeyId(credentials.accessKey());
        storageCredentials.setAccessKeySecret(credentials.secretKey());
        storageCredentials.setSecurityToken(credentials.sessionToken());
        storageCredentials.setExpire(3600);

        StorageConfigGetData.StorageOutput storageOutput = new StorageConfigGetData.StorageOutput();
        storageOutput.setBucket("my-bucket");
//            storageOutput.setBucket(this.bucketName);
        storageOutput.setCredentials(storageCredentials);
//            storageOutput.setEndpoint(endpoint);
//            storageOutput.setEndpoint(this.endpoint);
        storageOutput.setEndpoint("http://192.168.0.80:9000");
        storageOutput.setRegion("hz");
//            storageOutput.setRegion("hz");
        storageOutput.setProvider("minio");

//            QueryWrapper<FeisuanWayPointTaskInfo> queryWrapper = new QueryWrapper<>();
//            queryWrapper.orderByDesc("id");
//            queryWrapper.last("limit 1");
//            FeisuanWayPointTaskInfo feisuanWayPointTaskInfo = wayPointTaskInfoMapper.selectOne(queryWrapper);

        storageOutput.setObjectKeyPrefix("wayline/" + LocalDateTime.now());

        StorageConfigGetData storageConfigGetData = new StorageConfigGetData();
        storageConfigGetData.setOutput(storageOutput);
        storageConfigGetData.setResult(0);
        DeviceConfigResponse<StorageConfigGetData> deviceConfigResponse = new DeviceConfigResponse<>();

        deviceConfigResponse.setBid(bid);
        deviceConfigResponse.setTid(tid);
        deviceConfigResponse.setData(storageConfigGetData);

        deviceConfigResponse.setTimestamp(System.currentTimeMillis());
        deviceConfigResponse.setMethod("storage_config_get");
        deviceConfigResponse.setGateway(gateway);


        log.info("DefaultStorageConfigGetHandler {}", JSONObject.toJSONString(deviceConfigResponse));

        MqttMessage message = new MqttMessage();
        message.setQos(0);
        message.setRetained(true);
        message.setPayload(com.alibaba.fastjson.JSONObject.toJSONString(deviceConfigResponse).getBytes());
        MqttClient mqttClient = new MqttClient("tcp://120.211.119.131:1883", "feisuan-mqtt-producer-client", new MemoryPersistence());
        MqttConnectOptions connOpts = new MqttConnectOptions();
        connOpts.setUserName("feisuan");
        connOpts.setPassword("feisuan123456".toCharArray());
        mqttClient.connect(connOpts);

        mqttClient.publish("thing/product/" + gateway + "/requests_reply", message);


//            GetStsTokenResponse getStsTokenResponse = new GetStsTokenResponse();
//            getStsTokenResponse.setSecurityToken(response.getCredentials().getSecurityToken());
//            getStsTokenResponse.setAccessKeyId(response.getCredentials().getAccessKeyId());
//            getStsTokenResponse.setAccessKeySecret(response.getCredentials().getAccessKeySecret());


        return Boolean.TRUE;
//    } catch(ClientException |
//    com.aliyuncs.exceptions.ClientException e)
//
//    {
//        log.error("Failed：", e);
//        return Boolean.FALSE;
//    }

    }
}
